import { defineStore } from 'pinia'
// 权限路由
import { homeRouters } from '@/api/public'
// 相关数据处理逻辑
import router from '@/router'
import { ElMessageBox } from 'element-plus'
import { find } from '@u/tree'
import user from './user'

export default defineStore('guarder', {
	state: () => ({
		pageInfoError: '', // 512错误
		cachedComponents: [], // 缓存页面数据
		Menus: [], // 菜单数据
		addRouter: [], // 动态添加的路由
		BreadcrumbList: {} // 面包屑数据
	}),
	actions: {
		// 生成路由
		GenerateRoutes() {
			return new Promise((resolve) => {
				// 向后端请求路由数据
				homeRouters().then((res) => {
					if (res?.data?.length) {
						const { Menus, Routes, BreadcrumbList } = filterAsyncRouter(clone(res.data))
						this.Menus = Menus
						this.BreadcrumbList = BreadcrumbList
						// 添加首页路由、404路由
						this.addRouter = [
							{
								path: '/',
								name: '/',
								redirect: find(Menus, true, (item) => !item.children).path,
								meta: {
									hideTabs: true
								}
							},
							...Routes,
							{
								path: '/:pathMatch(.*)',
								name: '/:pathMatch(.*)',
								redirect: '/404',
								meta: {
									hideTabs: true
								}
							}
						]
						this.addRouter.forEach((item) => {
							if (item.parentName) {
								router.addRoute(item.parentName, item)
							} else {
								router.addRoute(item)
							}
						})
						// this.RoutersList = [...new Set(router.getRoutes().map((item) => item.path))];
						resolve()
					} else {
						ElMessageBox.alert('该角色用户暂无可视页面，请管理员分配角色权限！', '系统提示', {
							confirmButtonText: '确定',
							callback: () => {
								user().LogOut()
								window.location.reload()
							}
						})
					}
				})
			})
		}
	}
})

/*
 * 处理解决import动态加载组件 打包部署为空的问题
 * **为通配符,vite不支持require导入方式,故用import.meta.glob(vite动态导入)
 * import.meta.glob
 * 该方法匹配到的文件默认是懒加载，通过动态导入实现，构建时会分离独立的 chunk，是异步导入，返回的是 Promise
 * import.meta.globEager
 * 该方法是直接导入所有模块，并且是同步导入，返回结果直接通过 for...in循环就可以操作
 */
const modules = import.meta.glob('../views/**/*.vue')

// 遍历后台传来的路由字符串，转换为组件对象  动态添加路由
function filterAsyncRouter(data) {
	const RoutesData = Object.create(null),
		MenusData = Object.create(null)

	// 数据转换为对象
	data.forEach((item) => {
		/**
		 * id 数据ID
		 * parentId 父类ID
		 * component .vue文件路径
		 * layoutPath 布局路径 layoutPath == undefined为默认布局，layoutPath == 'ParentView'全屏布局，modules[`../views/${layoutPath}.vue`]自定义页面布局
		 * icon 菜单图标
		 * menuName 菜单名称
		 * menuType 菜单类型  M——目录、C——菜单
		 * path 菜单路由
		 * visible 是否显示
		 * isCache 是否缓存
		 * orderNum 排序
		 */
		const { id, parentId, layoutPath, icon, menuName, menuType, path, visible, isCache, orderNum } = item
		let { component } = item
		if (parentId == '0' && menuType == 'M' && !component) {
			component = () => import('@/extension/layout.vue')
		} else if (parentId !== '0' && menuType == 'M' && !component) {
			// 非第一层目录布局为 ParentView，固定写法不可调整
			component = 'ParentView'
		} else {
			component = modules[`../views/${component}.vue`] || ''
		}
		// if (component == '') return;
		// 无目录菜单
		if (parentId == '0' && menuType == 'C') {
			// 布局 layoutPath为默认布局，layoutPath == 'ParentView'全屏布局，modules[`../views/${layoutPath}.vue`]自定义页面布局
			const layout = !layoutPath
				? () => import('@/extension/layout.vue')
				: layoutPath == 'ParentView'
				? () => import('@/extension/ParentView/index.vue')
				: modules[`../views/${layoutPath}.vue`]
			const parentName = !layoutPath ? '/Layout' : layoutPath == 'ParentView' ? '/ParentView' : `/${layoutPath}`
			// 添加布局页面
			if (!router.hasRoute(parentName)) {
				router.addRoute({
					name: parentName,
					path: parentName,
					component: layout
				})
			}
			const Path = !/^(\/)/.test(path) ? `/${path}` : path
			RoutesData[id] = {
				parentName,
				parentId,
				component,
				meta: { title: menuName, icon, keepAlive: isCache == 1, hidden: visible == 1 },
				path: Path,
				name: item.component || Path,
				orderNum,
				id
			}
		} else {
			const Path = parentId == '0' ? (!/^(\/)/.test(path) ? `/${path}` : path) : path
			RoutesData[id] = {
				component,
				meta: { title: menuName, icon, keepAlive: isCache == 1, hidden: visible == 1 },
				name: item.component || Path,
				path: Path,
				parentId,
				orderNum,
				id
			}
		}
		// 左边菜单数据
		if (visible !== 1) {
			const Path = parentId == '0' ? (!/^(\/)/.test(path) ? `/${path}` : path) : path
			MenusData[id] = {
				component,
				meta: { title: menuName, icon, keepAlive: isCache == 1, hidden: visible == 1 },
				name: item.component || Path,
				path: Path,
				parentId,
				orderNum,
				id
			}
		}
	})
	// 组成路由树形结构 拉平处理keep-alive缓存问题
	function parentFn(item, parent) {
		if (!item.path.includes(parent.path)) item.path = `${parent.path}/${item.path}`

		if (parent.component === 'ParentView') {
			parentFn(item, RoutesData[parent.parentId])
		} else {
			if (!parent.children) parent.children = []
			parent.children.push(item)
		}
	}

	const Routes = []
	for (const key in RoutesData) {
		const item = RoutesData[key]
		if (item.parentId == '0') {
			Routes.push(item)
		} else {
			const parent = RoutesData[item.parentId]
			if (parent) {
				parentFn(item, parent)
			}
		}
	}

	// 删除ParentView目录路由
	function RoutesFn(data) {
		data.map((item, i) => {
			if (item.component === 'ParentView') data.splice(i, 1)
			if (item.children?.length) RoutesFn(item.children)
		})
		return data
	}

	// 组成菜单树形结构
	const Menus = []
	for (const key in MenusData) {
		const item = MenusData[key]
		if (item.parentId == '0') {
			Menus.push(item)
			Menus.sort((a, b) => {
				return a.orderNum - b.orderNum
			})
		} else {
			const parent = MenusData[item.parentId]
			if (parent) {
				if (!parent.children) parent.children = []
				parent.children.push(item)
				parent.children.sort((a, b) => {
					return a.orderNum - b.orderNum
				})
			}
		}
	}
	// 菜单path拼接
	function MenusFn(data, parentPath) {
		return data.map((item) => {
			if (item.parentId != 0) item.path = `${parentPath}/${item.path}`
			if (item.children?.length) MenusFn(item.children, item.path)
			return item
		})
	}
	const finallyMenus = MenusFn(cloneDeep(Menus))

	// Breadcrumb 面包屑数据处理
	const BreadcrumbList = {}
	function BreadcrumbFn(data, list = []) {
		data.map((item) => {
			if (item.children?.length) {
				const data = [
					...list,
					{
						title: item.meta.title,
						path: find(item.children, true, (item2) => !item2.children).path
					}
				]
				BreadcrumbFn(item.children, data)
			} else {
				const data = [...list, { title: item.meta.title, path: item.path }]
				BreadcrumbList[item.path] = data
			}
		})
	}
	BreadcrumbFn(finallyMenus)

	return {
		Menus: finallyMenus,
		Routes: RoutesFn(cloneDeep(Routes)),
		BreadcrumbList
	}
}
